package com.haoshuang.zhouzhoubang.utils

import android.app.ProgressDialog
import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Matrix
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.os.Handler
import android.os.Message
import android.provider.MediaStore
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import com.mufeng.libs.utils.ktx.runOnUIThread
import java.io.*
import java.net.URL
import java.nio.file.Files
import java.util.*


/**图片保存工具单例-通过donwloadImg()来执行*/
object DownloadSaveImg {
    private var context: Context? = null
    private var filePath: String? = null
    private var filePath2: String? = null
    private var mBitmap: Bitmap? = null
    private var mBitmap2: Bitmap? = null
    private var mSaveMessage = "失败"
    private const val TAG = "DownloadSaveImg"
    private var mSaveDialog: ProgressDialog? = null
    fun donwloadImg(contexts: Context?, imgUrlPaths: String?) {
        context = contexts
        filePath = imgUrlPaths
        mSaveDialog = ProgressDialog.show(context, "保存图片", "图片正在保存中，请稍等...", true)
        Thread(saveFileRunnable).start() // 开启一个主线程
    }

    /**将两个图片的url合成一张保存*/
    fun donwloadImg2(contexts: Context?, firstPaths: String?, secondPaths: String?) {
        context = contexts
        filePath = firstPaths
        filePath2 = secondPaths
        mSaveDialog = ProgressDialog.show(context, "保存图片", "图片正在保存中，请稍等...", true)
        Thread(saveFileRunnable2).start() // 开启一个主线程
    }

    /**直接传入bitmap并在主线程中执行保存到相册操作
     * @param bitmap 要保存的位图
     */
    fun save2Bitmap(contexts: Context?, bitmap: Bitmap) {
        context = contexts
        mBitmap = bitmap
        mSaveDialog = ProgressDialog.show(context, "保存图片", "图片正在保存中，请稍等...", true)
        Thread(saveBitmap).start() // 开启一个主线程
    }

    /**合成图片主线程*/
    private val saveFileRunnable2 = Runnable {
        try {
            if (!TextUtils.isEmpty(filePath)) { //网络图片
                // 对资源链接
                val url = URL(filePath)
                val url2 = URL(filePath2)
                //打开输入流
                val inputStream = url.openStream()
                val inputStream2 = url2.openStream()
                //对网上资源进行下载转换位图图片
                mBitmap = BitmapFactory.decodeStream(inputStream)
                mBitmap2 = BitmapFactory.decodeStream(inputStream2)
                inputStream.close()
                inputStream2.close()
            }
            if (mBitmap2 != null && mBitmap2 != null){
                saveFile(mBitmap?.let { mergeBitmap(it, mBitmap2!!,30f,0f) })
            }
            mSaveMessage = "图片保存成功！"
        } catch (e: IOException) {
            mSaveMessage = "图片保存失败！"
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        messageHandler.sendMessage(messageHandler.obtainMessage())  // 发送通知
    }

    private val saveFileRunnable = Runnable {
        try {
            if (!TextUtils.isEmpty(filePath)) { //网络图片
                // 对资源链接
                val url = URL(filePath)
                //打开输入流
                val inputStream = url.openStream()
                //对网上资源进行下载转换位图图片
                mBitmap = BitmapFactory.decodeStream(inputStream)
                inputStream.close()
            }
            saveFile(mBitmap)
            mSaveMessage = "图片保存成功！"
        } catch (e: IOException) {
            mSaveMessage = "图片保存失败！"
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        messageHandler.sendMessage(messageHandler.obtainMessage())  // 发送通知
    }

    private val saveBitmap = Runnable {
        try {
            saveFile(mBitmap)
            mSaveMessage = "图片保存成功！"
        } catch (e: IOException) {
            mSaveMessage = "图片保存失败！"
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        messageHandler.sendMessage(messageHandler.obtainMessage())  // 发送通知
    }


    /**通知*/
    private val messageHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            mSaveDialog!!.dismiss()
            Log.d(TAG, mSaveMessage)
            Toast.makeText(context, mSaveMessage, Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 保存图片
     * @param bm
     * @throws IOException
     */
    @Throws(IOException::class)
    fun saveFile(bm: Bitmap?) {
        val dirFile = File(Environment.getExternalStorageDirectory().path)
        if (!dirFile.exists()) {
            dirFile.mkdir()
        }
        val fileName = UUID.randomUUID().toString() + ".jpg"
        val myCaptureFile = File(Environment.getExternalStorageDirectory().path + "/DCIM/Camera/" + fileName)
        val bos = BufferedOutputStream(FileOutputStream(myCaptureFile))
        bm!!.compress(Bitmap.CompressFormat.JPEG, 80, bos)
        bos.flush()
        bos.close()
        //把图片保存后声明这个广播事件通知系统相册有新图片到来
        val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
        val uri = Uri.fromFile(myCaptureFile)
        intent.data = uri
        context!!.sendBroadcast(intent)
    }

    /**合成图片到指定位置*/
    fun mergeBitmap(firstBitmap: Bitmap, secondBitmap: Bitmap, left: Float, top: Float): Bitmap? {
        val bitmap = Bitmap.createBitmap(firstBitmap.width, firstBitmap.height, firstBitmap.config)
        val canvas = Canvas(bitmap)
        canvas.drawBitmap(firstBitmap, Matrix(), null)
        Log.e(TAG, "mergeBitmap: 高度：${secondBitmap.height}宽度：${secondBitmap.width}")
        /*val newW = 48.0f
        val newH = 48.0f
        val matrix = Matrix()
        val scaleW = newW/secondBitmap.width
        val scaleH = newH/secondBitmap.height
        matrix.postScale(scaleW,scaleH) // 设置宽高的缩放比例因子
        val bim = Bitmap.createBitmap(secondBitmap,0,0,secondBitmap.width,secondBitmap.height,matrix,true)
        val top = firstBitmap.height - bim.height*/
        canvas.drawBitmap(secondBitmap,left,top,null)
        return bitmap
    }

    /**
     * 将视频保存到系统相册
     */
    fun saveVideoToAlbum(context: Context, videoFile: String): Boolean {
        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            saveVideoToAlbumBeforeQ(context, videoFile)
        } else {
            saveVideoToAlbumAfterQ(context, videoFile)
        }
    }

    /**
     * 获取视频的contentValue
     */
    fun getVideoContentValues(context: Context, paramFile: File, timestamp: Long): ContentValues {
        val localContentValues = ContentValues()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            localContentValues.put(
                MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM
                        + File.separator + context.packageName
            )
        }
        localContentValues.put(MediaStore.Video.Media.TITLE, paramFile.name)
        localContentValues.put(MediaStore.Video.Media.DISPLAY_NAME, paramFile.name)
        localContentValues.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
        localContentValues.put(MediaStore.Video.Media.DATE_TAKEN, timestamp)
        localContentValues.put(MediaStore.Video.Media.DATE_MODIFIED, timestamp)
        localContentValues.put(MediaStore.Video.Media.DATE_ADDED, timestamp)
        localContentValues.put(MediaStore.Video.Media.SIZE, paramFile.length())
        return localContentValues
    }


    private fun saveVideoToAlbumAfterQ(context: Context, videoFile: String): Boolean {
        return try {
            val contentResolver = context.contentResolver
            val tempFile = File(videoFile)
            val contentValues = getVideoContentValues(context, tempFile, System.currentTimeMillis())
            val uri =
                contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues)
            copyFileAfterQ(context, contentResolver, tempFile, uri)
            contentValues.clear()
            contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0)
            context.contentResolver.update(uri!!, contentValues, null, null)
            context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
            runOnUIThread {
                Toast.makeText(DownloadSaveImg.context, "保存成功", Toast.LENGTH_SHORT).show()
            }
            true
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            runOnUIThread {
                Toast.makeText(DownloadSaveImg.context, "保存失败", Toast.LENGTH_SHORT).show()
            }
            false
        }
    }

    @Throws(IOException::class)
    private fun copyFileAfterQ(
        context: Context,
        localContentResolver: ContentResolver,
        tempFile: File,
        localUri: Uri?
    ) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
            context.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q
        ) {
            //拷贝文件到相册的uri,android10及以上得这么干，否则不会显示。可以参考ScreenMediaRecorder的save方法
            val os = localContentResolver.openOutputStream(localUri!!)
            Files.copy(tempFile.toPath(), os)
            os!!.close()
            tempFile.delete()
        }
    }


    private fun saveVideoToAlbumBeforeQ(context: Context, videoFile: String): Boolean {
        val picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
        val tempFile = File(videoFile)
        val destFile = File(picDir, context.packageName + File.separator + tempFile.name)
        var ins: FileInputStream? = null
        var ous: BufferedOutputStream? = null
        return try {
            ins = FileInputStream(tempFile)
            ous = BufferedOutputStream(FileOutputStream(destFile))
            var nread = 0L
            val buf = ByteArray(1024)
            var n: Int
            while (ins.read(buf).also { n = it } > 0) {
                ous.write(buf, 0, n)
                nread += n.toLong()
            }
            MediaScannerConnection.scanFile(
                context, arrayOf(destFile.absolutePath), arrayOf("video/*")
            ) { path: String?, uri: Uri? -> }
            runOnUIThread {
                Toast.makeText(DownloadSaveImg.context, "保存成功", Toast.LENGTH_SHORT).show()
            }

            true
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            runOnUIThread {
                Toast.makeText(DownloadSaveImg.context, "保存失败", Toast.LENGTH_SHORT).show()
            }
            false
        } finally {
            try {
                ins?.close()
                ous?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

}